package com.eedi.framework.tenant.framework.tenant;

import cn.hutool.core.util.StrUtil;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException;
import com.eedi.framework.common.exception.util.PreconditionsUtils;
import com.eedi.framework.common.util.cache.CacheUtils;
import com.eedi.framework.tenant.core.service.TenantFrameworkService;
import com.eedi.framework.tenant.enums.SysTenantErrorCodeConstants;
import com.eedi.framework.tenant.service.TenantService;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Duration;
import java.util.List;

/**
 * Tenant 框架 Service 实现类
 *
 * @author 永聚长青源码
 */
@Service
public class TenantFrameworkServiceImpl implements TenantFrameworkService {

    @Resource
    TenantService tenantService;

    /**
     * 针对 {@link #getTenantIds()} 的缓存
     */
    private final LoadingCache<Object, List<String>> getTenantIdsCache = CacheUtils.buildCache(
            Duration.ofMinutes(1L),
            // 过期时间 1 分钟
            new CacheLoader<>() {

                @Override
                public List<String> load(Object key) {
                    return tenantService.getTenantIdList();
                }

            });

    /**
     * 针对 {@link #validTenant(String)} 的缓存
     */
    private final LoadingCache<String, Boolean> validTenantCache = CacheUtils.buildCache(
            Duration.ofMinutes(1L),
            // 过期时间 1 分钟
            new CacheLoader<>() {
                @Override
                public Boolean load(String id) {
                    return tenantService.validTenant(id);
                }

            });

    @Override
    @SneakyThrows
    public List<String> getTenantIds() {
        try {
            return getTenantIdsCache.get(Boolean.TRUE);
        }catch (UncheckedExecutionException e){
            throw e.getCause();
        }
    }

    @Override
    @SneakyThrows
    public void validTenant(String id) {
        PreconditionsUtils.checkArgument(StrUtil.isNotBlank(id), SysTenantErrorCodeConstants.SYS_TENANT_ID_NOT_EXISTS);
        try {
            validTenantCache.get(id);
        }catch (UncheckedExecutionException e){
            throw e.getCause();
        }
    }

}
